#ifndef __HELPER_H__
#define __HELPER_H__


#pragma once


CString    IntToStr(int value);
CString    UIntToStr(UINT value);
CString    BoolToStr(bool value);
CString    GetStringProperty(LPDISPATCH pDisp, LPCTSTR PropName);
bool       ExtensionIs(LPCTSTR FileName, LPCTSTR Ext);
CString    ChangeFileExt(LPCTSTR FileName, LPCTSTR Ext);
CString    ComcatFileName(LPCTSTR Path, LPCTSTR FileName);


template<class T>
T GetDispatchProperty(LPDISPATCH pDisp, LPCTSTR PropName, REFIID riid)
{
	USES_CONVERSION;
	CComDispatchDriver dispdrv(pDisp);
	VARIANT var;
	VariantInit(&var);

	HRESULT hr = dispdrv.GetPropertyByName(T2CW(PropName), &var);
	if (FAILED(hr)) return NULL;
	switch (var.vt)
	{
	case VT_DISPATCH:
		{
			if (var.pdispVal == NULL)
			{
				VariantClear(&var);
				return NULL;
			}
			T ret = NULL;
			hr = var.pdispVal->QueryInterface(riid, (LPVOID*)&ret);
			VariantClear(&var);
			return (SUCCEEDED(hr)) ? ret : NULL;
		}
		break;
	case (VT_DISPATCH | VT_BYREF):
		{
			if ((*var.ppdispVal) == NULL)
			{
				VariantClear(&var);
				return NULL;
			}
			T ret = NULL;
			hr = (*var.ppdispVal)->QueryInterface(riid, (LPVOID*)&ret);
			VariantClear(&var);
			return (SUCCEEDED(hr)) ? ret : NULL;
		}
		break;
	default:
		VariantClear(&var);
		return NULL;
		break;
	}
}

template<class T>
bool InterfaceIs(IDispatch* pDisp, REFIID riid)
{
	T* t = NULL;
	HRESULT hr = pDisp->QueryInterface(riid, (LPVOID*)&t);
	if (SUCCEEDED(hr) && t!=NULL)
	{
		t->Release();
		return true;
	}
	else
	{
		return false;
	}
}


template<class T>
T* InterfaceAs(IDispatch* pDisp, REFIID riid)
{
	T* t = NULL;
	HRESULT hr = pDisp->QueryInterface(riid, (LPVOID*)&t);
	if (SUCCEEDED(hr) && t!=NULL)
	{
		return t;
	}
	else
	{
		return NULL;
	}
}


template<class T>
long GetEnumCount(T* t)
{
	long lCount = 0;
	HRESULT hr = t->get_Count(&lCount);
	if (SUCCEEDED(hr))
		return lCount;
	else
		return 0;
}


template<class TEnum, class TItem>
TItem* GetEnumItem(TEnum* t, long index, REFIID riid)
{
	_variant_t varIndex(index);
	IDispatch* pDisp = NULL;
	HRESULT hr = t->Item(varIndex, &pDisp);
	if (FAILED(hr) || pDisp==NULL)
		return NULL;
	TItem* pItem = NULL;
	hr = pDisp->QueryInterface(riid, (LPVOID*)&pItem);
	pDisp->Release();
	if (SUCCEEDED(hr) && pItem!=NULL)
		return pItem;
	else
		return NULL;
}


template<class TEnum, class TItem>
TItem* GetEnumItem2(TEnum* t, long index, REFIID riid)
{
	_variant_t varIndex(index);
	TItem* pItem = NULL;
	HRESULT hr = t->Item(varIndex, &pItem);
	if (FAILED(hr) || pItem==NULL)
		return NULL;
	else
		return pItem;
}


#endif
